package perform.query;

import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import perform.mappings.ClassMappings;
import perform.type.Type;
import perform.utilities.ValueParser;

public class AbstractQuery implements Query {
	
	protected String query;
	protected PreparedStatement preparedStatement;
	protected ValueParser parser;
	
	protected AbstractQuery(){
		parser = new ValueParser();
	}
	
	@SuppressWarnings("unchecked")
	protected void setValue(int columnIndex, Object value) throws Exception{
		if(value == null) {
			preparedStatement.setObject(columnIndex, value);
		} else if(value instanceof Enum || value instanceof CharSequence){
			preparedStatement.setString(columnIndex, value.toString());
		} else if(value instanceof Type){
			setValue(columnIndex, ClassMappings.getIDField((Class<? extends Type>) value.getClass()).get(value));
		} else if(value instanceof char[]){
			preparedStatement.setString(columnIndex, String.valueOf((char[])value));
		} else if(value instanceof Character[]){
			Character[] chars = (Character[]) value;
			String string = "";
			for (int i = 0; i < chars.length; i++) {
				string += chars[i];
			}
			preparedStatement.setString(columnIndex, string);
		} else if(value instanceof Character){
			preparedStatement.setString(columnIndex, String.valueOf((Character)value));
		} else {
			preparedStatement.setObject(columnIndex, value);
		}
	}
	
	@Override
	public String getQuery() {
		return query;
	}
	@Override
	public PreparedStatement getPreparedStatement() {
		return preparedStatement;
	}
	@Override
	public int executeUpdate() throws SQLException {
		return preparedStatement.executeUpdate();
	}
	@Override
	public ResultSet executeQuery() throws SQLException {
		return preparedStatement.executeQuery();
	}
	@Override
	public void close() throws SQLException {
		preparedStatement.close();
	}
	@Override
	public void setGeneratedKey(Type type) throws Exception {
		ResultSet rs = preparedStatement.getGeneratedKeys();
		if(rs.next()){
			Field field = ClassMappings.getIDField(type.getClass());
			field.set(type, parser.parseValue(field.getType(), "GENERATED_KEY", rs));
		}
	}

}
